/*
SWFObject的流行，得益于微软在IE中加了控件激活设置(目前已经去掉限制)
而通过调用外部脚本生成插入Flash的HTML，却能避开激活限制。
通过使用SWFObject，插入Flash已经变得很简单
而moo的Swiff的创意来自SWFObject，正如moo来源于Prototype
通过Swiff类，可以学到封装UI组件，需要提供的基本方法：
1.事件支持(本例使用callback而不是Events的实现，一般情况下使用Events类的接口实现)
2.配置可选项(Options类setOptions的接口实现)
3.将组件添加到DOM中的方法
4.提供UI组件中重要HTML Element的引用
至于如何使用Swiff类，可以看moo的官方Swiff教程
*/
var Swiff = new Class({

 //setOptions接口实现，因为本类的特殊性，没有使用Events的事件接口实现
 Implements: [Options],

 options: {
  id: null, //生成object/embed的id
  height: 1, //高度
  width: 1, //宽度
  container: null, //容器
  properties: {}, //属性集
  params: { //参数集
   quality: 'high',//播放质量
   allowscrīptAccess: 'always',
   wMode: 'transparent',//透明模式
   swLiveConnect: true//是否启动Java，以支持fscommand
  },
  callBacks: {}, //回调方法集
  vars: {} //变量集
 },

 //获取指向的HTML Element对象
 toElement: function(){
  return this.object;
 },

 /*
 path为swf文件路径
 */
 initialize: function(path, options){
  //生成唯一实例名
  this.instance = 'Swiff_' + $time();

  this.setOptions(options);
  options = this.options;

  //得到唯一id
  var id = this.id = options.id || this.instance;
  //容器
  var container = $(options.container);
 
  //使用唯一实例名初始化当前对象的回调方法集
  Swiff.CallBacks[this.instance] = {};

  var params = options.params, vars = options.vars, callBacks = options.callBacks;
  var properties = $extend({height: options.height, width: options.width}, options.properties);

  //声明局部变量，用于下面的闭包中的引用
  var self = this;

  //复制回调方法
  for (var callBack in callBacks){
   Swiff.CallBacks[this.instance][callBack] = (function(option){
    return function(){
     return option.apply(self.object, arguments);
    };
   })(callBacks[callBack]);
   //最终通过flashVars参数传给swf
   vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack;
  }

  params.flashVars = Hash.toQueryString(vars);
  //IE使用classid，其它浏览器声明contentType，注意文件路径对应的属性
  if (Browser.Engine.trident){
   properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
   params.movie = path;
  } else {
   properties.type = 'application/x-shockwave-flash';
   properties.data = path;
  }
  /*
  字符串拼接出最终输出的HTML代码
  如果要考虑效率，这里应该用数组，否则使用字符串的substitute方法会更优雅
  */
  var build = '<object id="' + id + '"';
  //遍历拼接属性
  for (var property in properties) build += ' ' + property + '="' + properties[property] + '"';
  build += '>';
  //遍历拼接参数
  for (var param in params){
   if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />';
  }
  build += '</object>';
  //因为属性和参数太多，如果直接new Element的话会比较烦琐，所以直接new一个临时的div，设置其HTML再返回子节点
  this.object =  ((container) ? container.empty() : new Element('div')).set('html', build).firstChild;
 },

 //将当前对象替换element,也许是为了避免模块间藕合太过，所以没有直接使用Element的replaces方法
 replaces: function(element){
  element = $(element, true);
  element.parentNode.replaceChild(this.toElement(), element);
  return this;
 },

 //附加到element中，这里也没有直接使用Element的inject方法
 inject: function(element){
  $(element, true).appendChild(this.toElement());
  return this;
 },

 //方法调用
 remote: function(){
  return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments));
 }

});

//回调方法集
Swiff.CallBacks = {};

//swf到js的方法调用
Swiff.remote = function(obj, fn){
 var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascrīpt">' + __flash__argumentsToXML(arguments, 2) + '</invoke>');
 return eval(rs);
};